package com.millstein.service.impl;

import com.millstein.enums.coupon.CouponStateEnum;
import com.millstein.enums.coupon.LockStateEnum;
import com.millstein.enums.order.ProductOrderStateEnum;
import com.millstein.feign.OrderFeignService;
import com.millstein.model.CouponRecordDO;
import com.millstein.model.CouponRecordMessage;
import com.millstein.model.CouponTaskDO;
import com.millstein.mapper.CouponTaskMapper;
import com.millstein.service.CouponTaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.millstein.util.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author millstein
 * @since 2021-09-19
 */
@Service
@Slf4j
public class CouponTaskServiceImpl extends ServiceImpl<CouponTaskMapper, CouponTaskDO> implements CouponTaskService {

    @Autowired
    private CouponRecordServiceImpl couponRecordService;

    @Autowired
    private OrderFeignService orderFeignService;

    /**
     * 解锁优惠券
     *
     * @param couponRecordMessage 消息的内容
     * @return
     */
    @Override
    @Transactional
    public boolean doReleaseCouponRecord(CouponRecordMessage couponRecordMessage) {
        CouponTaskDO dbTask = this.getById(couponRecordMessage.getTaskId());

        // 锁定优惠券的记录不存在的情况
        if (dbTask == null) {
            log.warn("锁定的优惠券记录不存在：{}", couponRecordMessage);
            return false;
        }

        if (!dbTask.getLockState().equals(LockStateEnum.LOCK.name())) {
            log.warn("锁定状态不是LOCK，不进行处理：{}", couponRecordMessage);
            return false;
        }

        String outTradeNo = couponRecordMessage.getOutTradeNo();

        JsonData result = orderFeignService.getProductOrderStateByOutTradeNo(outTradeNo);

        // 查询到订单的情况
        if (result.getCode() == 0) {
            String state = (String) result.getData();
            // 当查到的订单状态是NEW时，由于无法知晓是否是由于网络等原因造成的订单状态未修改，所以保守点的做法就是重新投递
            // TODO 这里可以添加对重新投递次数的判断，满多少次就不重新投递，而是记录到数据库里，等待人工进行排查
            if (state.equals(ProductOrderStateEnum.NEW.name())) {
                log.warn("订单的状态是NEW，返回给消息队列，重新投递：{}", couponRecordMessage);
                return true;
            }
            // 当查到的订单状态是PAY时，这个时候是支付完成，走的就是正常流程
            if (state.equals(ProductOrderStateEnum.PAY.name())) {
                log.info("订单的状态是已支付，修改锁定优惠券记录的状态为FINISH：{}", couponRecordMessage);
                dbTask.setLockState(LockStateEnum.FINISH.name());
                this.updateById(dbTask);
                return false;
            }
        }

        // 代码如果走到这里，那么说明这个订单要么不存在，要么它的状态是已经取消的。所以这个时候我们要将优惠券释放，并取消掉本次的锁定记录
        log.warn("订单不存在，获取已被取消，修改锁定记录的状态是CANCEL，并将优惠券记录状态改为NEW：{}", couponRecordMessage);
        dbTask.setLockState(LockStateEnum.CANCEL.name());
        this.updateById(dbTask);

        CouponRecordDO dbRecord = couponRecordService.getById(dbTask.getCouponRecordId());
        dbRecord.setUseState(CouponStateEnum.NEW.name());
        couponRecordService.updateById(dbRecord);
        return false;
    }
}
